package com.ruoyi.business.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ruoyi.base.domain.BaseBsBd;
import com.ruoyi.base.domain.BaseBsProject;
import com.ruoyi.base.domain.vo.BaseBsBdVo;
import com.ruoyi.base.domain.vo.BaseBsFbfxVo;
import com.ruoyi.base.domain.vo.BaseBsZdVo;
import com.ruoyi.base.mapper.BaseBsBdMapper;
import com.ruoyi.base.mapper.BaseBsFbfxMapper;
import com.ruoyi.base.mapper.BaseBsProjectMapper;
import com.ruoyi.base.mapper.BaseBsZdMapper;
import com.ruoyi.business.entity.ApproveUser;
import com.ruoyi.business.entity.bo.*;
import com.ruoyi.business.service.BusinessProcessService;

import com.ruoyi.cm.domain.CmBsProcessInspection;
import com.ruoyi.cm.domain.CmBsQs;
import com.ruoyi.cm.domain.bo.*;
import com.ruoyi.cm.domain.vo.CmBsProcessInspectionVo;
import com.ruoyi.cm.mapper.CmBsProcessInspectionMapper;
import com.ruoyi.cm.mapper.CmBsQsMapper;
import com.ruoyi.cm.service.*;
import com.ruoyi.common.annotation.Translation;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.ma.domain.MaMaterialPlan;
import com.ruoyi.ma.domain.MaReportFormPayment;
import com.ruoyi.ma.domain.bo.MaMaterialPlanBo;
import com.ruoyi.ma.domain.vo.MaMaterialPlanVo;
import com.ruoyi.ma.domain.vo.MaReportFormPaymentVo;
import com.ruoyi.ma.mapper.MaMaterialPlanMapper;
import com.ruoyi.ma.mapper.MaReportFormPaymentMapper;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.domain.SysUserPower;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.mapper.SysUserPowerMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.workflow.service.IWfProcessService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.business.constant.BusinessConstants.*;

@RequiredArgsConstructor
@Service
public class BusinessProcessServiceImpl implements BusinessProcessService {

    private final IWfProcessService wfProcessService;

    private final ICmBsStartAdvanceService cmBsStartAdvanceService;

    private final ICmBaContractSheetsService iCmBaContractSheetsService;

    private final ICmBsContractInfoService iCmBsContractInfoService;
    //报表管理
    private final ICmReportService reportService;

    private final BaseBsBdMapper baseBsBdMapper;

    private final BaseBsZdMapper baseBsZdMapper;

    private final BaseBsFbfxMapper fbfxMapper;
    private final BaseBsProjectMapper projectMapper;

    private final SysUserMapper userMapper;

    private final SysUserPowerMapper userPowerMapper;

    private final SysUserPostMapper userPostMapper;

    private final SysPostMapper postMapper;

//    private final BaseBsProjectMapper projectMapper;

    private final CmBsProcessInspectionMapper processInspectionMapper;
    private final CmBsQsMapper qsMapper;

    private final MaMaterialPlanMapper planMapper;
    private final MaReportFormPaymentMapper paymentMapper;


    /**
     * 工序报验
     * @param bo
     * @return
     */
    @Override
    public Boolean startGXBYSPLCProcess(GxbysplcBo bo) {
        CmBsProcessInspection inspectionBo = new CmBsProcessInspection();
        inspectionBo.setApproveStatus("11");
        inspectionBo.setId(bo.getId());
        CmBsProcessInspectionVo inspectionVo = processInspectionMapper.selectVoById(bo.getId());
        if (ObjectUtils.isNotEmpty(inspectionVo)){
            bo.setGxName(inspectionVo.getName());
            BaseBsZdVo zdVo = baseBsZdMapper.selectVoById(inspectionVo.getZdId());
            if(zdVo!=null){
                bo.setBdName(zdVo.getBdName());
                bo.setZdName(zdVo.getName());
                if(StringUtils.isBlank(bo.getProjectName())) {
                    BaseBsBdVo bdVo = baseBsBdMapper.selectVoById(zdVo.getBdId());
                    bo.setProjectName(bdVo == null ? "" : bdVo.getProjectName());
                }
            }
            //分部分项,所有父分部分项名称拼接；
            BaseBsFbfxVo fbfxVo = fbfxMapper.selectVoById(inspectionVo.getFbfxId());
            String fbfxName = "";
            if(fbfxVo!=null) {
                List<BaseBsFbfxVo> voList = new ArrayList<>();
                voList.add(fbfxVo);
                BaseBsFbfxVo vo;
                Long parentId = fbfxVo.getParentId();
                for (; ; ) {
                    vo = fbfxMapper.selectVoById(parentId);
                    if (vo != null && vo.getParentId() != null) {
                        parentId = vo.getParentId();
                        voList.add(vo);
                    } else {
                        break;
                    }
                }
                for (int i = voList.size() - 1; i >= 0; i--) {
                    fbfxName = fbfxName + voList.get(i).getName() + "+";
                }
            }
            bo.setFbfxName(fbfxName.length() == 0 ? "" : fbfxName.substring(0, fbfxName.length() - 1).trim());
        }
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String proInsId = wfProcessService.startProcessByDefKey(GXBYSPLC_PROCESS_KEY, variables);
        inspectionBo.setProcInsId(proInsId);
        processInspectionMapper.updateById(inspectionBo);
        return Boolean.TRUE;
    }

    /**
     * 工序报验审批人
     * @param businessId
     * @return
     */
    @Override
    public ProcessPersonBo getGXBYSPLCPerson(Long businessId) {
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
//        bo.setJianshedanwei(new ApproveUser());
        return bo;
    }

    /**
     * 发起甲供材审批流程
     * @param bo
     * @return
     */
    @Override
    @Transactional
    public Boolean startJGCSPLCProcess(jgcsplcBo bo) {
        // 获取材料计划主表信息并保存到流程信息
        MaMaterialPlanVo planVo = planMapper.getById(bo.getPlanId());
        bo.setBdName(planVo.getBdName());
        bo.setZdName(planVo.getZdName());
        bo.setGysName(planVo.getDeptName());
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String proInsId = wfProcessService.startProcessByDefKey(JGC_PROCESS_KEY, variables);
        // 保存审批信息
        MaMaterialPlan maMaterialPlanBo = new MaMaterialPlan();
        maMaterialPlanBo.setWorkflowsStateus("11");
        maMaterialPlanBo.setPlanId(bo.getPlanId());
        maMaterialPlanBo.setProInsId(proInsId);
        planMapper.updateById(maMaterialPlanBo);
        return Boolean.TRUE;
    }

    /**
     * 获取 甲供材审批流程 预设审批人
     *
     * @param businessId
     * @return
     */
    @Override
    public ProcessPersonBo getJGCSPLCPerson(Long businessId) {
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setJianshedanwei(getjiansdw());
        return bo;
    }

    /**
     * 发起 甲供材报表审批流程
     * @param bo
     * @return
     */
    @Override
    @Transactional
    public Boolean startJGCBBSPLCProcess(jgcsplcBo bo) {
        MaReportFormPayment paymentBo = new MaReportFormPayment();
        paymentBo.setWorkflowsStateus("11");
        paymentBo.setReportId(bo.getReportId());
        paymentMapper.updateById(paymentBo);
        // 获取支付报表信息并保存到流程信息 @TODO
        MaReportFormPaymentVo paymentVo = paymentMapper.getByReportId(bo.getReportId());
        bo.setBdName(paymentVo.getBdName());
        bo.setZdName(paymentVo.getZdName());
        bo.setGysName(paymentVo.getDeptName());
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        wfProcessService.startProcessByDefKey(JGCBB_PROCESS_KEY, variables);
        return Boolean.TRUE;
    }

    @Override
    public ProcessPersonBo getJGCBBSPLCPerson(Long businessId) {
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setJianli(new ApproveUser(LoginHelper.getUserId(), LoginHelper.getNickName()));
        bo.setJianshedanwei(new ApproveUser(LoginHelper.getUserId(), LoginHelper.getNickName()));
        return bo;
    }

    /**
     * 发起 合同站点清单变更审批流程
     * @param bo
     * @return
     */
    @Override
    public Boolean startHTZDQDBGSPProcess(htzdqdlcBo bo) {
        // TODO 按需求做些业务的校验，如 是否允许发起等
        CmBaContractSheetsBo cmBaContractSheetsBo = new CmBaContractSheetsBo();
        cmBaContractSheetsBo.setBdId(bo.getBdId());
        cmBaContractSheetsBo.setZdId(bo.getZdId());
        cmBaContractSheetsBo.setChgApprovalStatus("11");
        BaseBsBdVo baseBsBdVo = baseBsBdMapper.selectVoById(bo.getBdId());
        if (ObjectUtils.isNotEmpty(baseBsBdVo)){
            bo.setBdName(baseBsBdVo.getName());
        }
        BaseBsZdVo baseBsZdVo = baseBsZdMapper.selectVoById(bo.getZdId());
        if (ObjectUtils.isNotEmpty(baseBsZdVo)){
            bo.setZdName(baseBsZdVo.getName());
        }
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String s = wfProcessService.startProcessByDefKey(HTZDQDBGSPLC_PROCESS_KEY, variables);
        cmBaContractSheetsBo.setProInsId(s);
        iCmBaContractSheetsService.updateApprovalStatusByBo(cmBaContractSheetsBo);
        return Boolean.TRUE;
    }

    /**
     * 获取合同站点清单变更审批流程预设审批人
     *
     * @param businessId
     * @return
     */
    @Override
    public ProcessPersonBo getHTZDQDBGSPPerson(Long businessId) {
        // TODO 按需求返回预设审批人 , 示例全用当前用户作为每个节点的审批人
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setJianshedanwei(getjiansdw());
        return bo;
    }

    //获取建设单位人员，暂写死为牛健，id 22
    private ApproveUser getjiansdw() {
        SysUser sysUser = userMapper.selectUserById(Long.parseLong("22"));
        if (sysUser != null) {
            return new ApproveUser(sysUser.getUserId(), sysUser.getNickName());
        }
        return new ApproveUser();
    }

    /**
     * 获取当前登录用户相关审批人
     * 1、根据当前登录用户获取所属项目；
     * 2、查询所属项目下的所有人员；（）
     * 3、过滤出对应岗位的人员，返回；
     */
    private ApproveUser getUserByPostCode(String postCode) {
        if (LoginHelper.isAdmin()) {
            return new ApproveUser();
        }
        List<SysUserPower> powers = userPowerMapper.selectList(new LambdaQueryWrapper<SysUserPower>().eq(SysUserPower::getUserId, LoginHelper.getUserId()));
        if (CollUtil.isEmpty(powers)) {
            return new ApproveUser();
        }
        Set<Long> powerIds = powers.stream().map(SysUserPower::getPowerId).collect(Collectors.toSet());
        List<BaseBsProject> projectList = projectMapper.selectList(new LambdaQueryWrapper<BaseBsProject>().in(BaseBsProject::getProjectId, powerIds));
        //登录用户关联项目；
        Set<Long> projectIds = new HashSet<>();
        Set<Long> bdids = new HashSet<>();
        //如果关联项目为空，就查询关联标段的所属项目；
        if (CollUtil.isEmpty(projectList)) {
            List<BaseBsBd> baseBsBds = baseBsBdMapper.selectList(new LambdaQueryWrapper<BaseBsBd>().in(BaseBsBd::getId, powerIds));
            if (CollUtil.isEmpty(baseBsBds)) {
                return new ApproveUser();
            }
            projectIds = baseBsBds.stream().map(BaseBsBd::getProjectId).collect(Collectors.toSet());
            bdids = baseBsBds.stream().map(BaseBsBd::getId).collect(Collectors.toSet());
        }
        Set<Long> projectIdset = projectList.stream().map(BaseBsProject::getProjectId).collect(Collectors.toSet());
        projectIds.addAll(projectIdset);
        projectIds.addAll(bdids);
        //2、查询关联该项目的所有人员；
        List<SysUserPower> powers1 = userPowerMapper.selectList(new LambdaQueryWrapper<SysUserPower>().in(SysUserPower::getPowerId,projectIds));
        Set<Long> userIds = powers1.stream().map(SysUserPower::getUserId).collect(Collectors.toSet());
        //查询对应岗位的用户id
        List<SysPost> sysPosts = postMapper.selectList(new LambdaQueryWrapper<SysPost>().eq(SysPost::getPostCode, postCode));
        if (CollUtil.isEmpty(sysPosts)) {
            return new ApproveUser();
        }
        Set<Long> postIds = sysPosts.stream().map(SysPost::getPostId).collect(Collectors.toSet());
        List<SysUserPost> sysUserPosts = userPostMapper.selectList(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getPostId, postIds));
        if (CollUtil.isEmpty(sysUserPosts)) {
            return new ApproveUser();
        }
        List<Long> userIdset = sysUserPosts.stream().map(SysUserPost::getUserId).filter(e-> userIds.contains(e)).collect(Collectors.toList());
        if(CollUtil.isEmpty(userIdset)){
            return new ApproveUser();
        }
        SysUser user = userMapper.selectById(userIdset.get(0));
        if (user == null) {
            return new ApproveUser();
        }
        return new ApproveUser(user.getUserId(), user.getNickName());
    }

    /**
     * 获取 工程款支付审核报表审批流程 预设审批人
     */
    @Override
    public ProcessPersonBo getGCKZHSHBBSPLCPerson(Long businessId) {
        // TODO 按需求返回预设审批人 , 示例全用当前用户作为每个节点的审批人
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setShenji(getUserByPostCode("sjry"));
        bo.setChushen(new ApproveUser());
        bo.setZhongshen(new ApproveUser());
        return bo;
    }

    /**
     * 发起 工程款支付审核报表审批流程
     */
    @Override
    public Boolean startGCKZHSHBBSPLCProcess(gckzfshbbsplcBo bo) {
        // TODO 按需求做些业务的校验，如 是否允许发起等
        CmReportBo reportBo = new CmReportBo();
        reportBo.setStatus("11");
        reportBo.setBdId(bo.getBdId());
        reportBo.setQsId(bo.getQsId());
        BaseBsBdVo baseBsBdVo = baseBsBdMapper.selectVoById(bo.getBdId());
        if (ObjectUtils.isNotEmpty(baseBsBdVo)){
            bo.setBdName(baseBsBdVo.getName());
        }
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String procInsId = wfProcessService.startProcessByDefKey(GCKZFSHBBSPLC_PROCESS_KEY, variables);
        reportBo.setProcInsId(procInsId);
        reportService.updateStatusByBo(reportBo);
        //设置发起审批日期到期数表的开始日期字段里
        CmBsQs qs = new CmBsQs();
        qs.setQsId(bo.getQsId());
        qs.setSettleBeginDate(new Date());
        qsMapper.updateById(qs);
        return Boolean.TRUE;
    }

    /**
     * 发起合同审批流程
     */
    @Override
    public Boolean startHTSPProcess(htsplcBo bo) {
        // TODO 按需求做些业务的校验，如 是否允许发起等
        CmBsContractInfoBo cmBsContractInfoBo = new CmBsContractInfoBo();
        cmBsContractInfoBo.setBdId(bo.getBdId());
        cmBsContractInfoBo.setContractId(bo.getContractId());
        cmBsContractInfoBo.setApprovalStatus("11");
        BaseBsBdVo baseBsBdVo = baseBsBdMapper.selectVoById(bo.getBdId());
        if (ObjectUtils.isNotEmpty(baseBsBdVo)){
            bo.setBdName(baseBsBdVo.getName());
        }
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String procInsId = wfProcessService.startProcessByDefKey(HTSPLC_PROCESS_KEY, variables);
        cmBsContractInfoBo.setProcInsId(procInsId);
        iCmBsContractInfoService.updateApprovalStatusByBo(cmBsContractInfoBo);
        return Boolean.TRUE;
    }

    /**
     * 发起合同变更审批流程
     */
    @Override
    public Boolean startHTBGSPProcess(htsplcBo bo) {
        // TODO 按需求做些业务的校验，如 是否允许发起等
        CmBsContractInfoBo cmBsContractInfoBo = new CmBsContractInfoBo();
        cmBsContractInfoBo.setBdId(bo.getBdId());
        cmBsContractInfoBo.setContractId(bo.getContractId());
        cmBsContractInfoBo.setChgApprovalStatus("11");
        BaseBsBdVo baseBsBdVo = baseBsBdMapper.selectVoById(bo.getBdId());
        if (ObjectUtils.isNotEmpty(baseBsBdVo)){
            bo.setBdName(baseBsBdVo.getName());
        }
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String procInsId = wfProcessService.startProcessByDefKey(HTBGSPLC_PROCESS_KEY, variables);
        cmBsContractInfoBo.setChgProcInsId(procInsId);
        iCmBsContractInfoService.updateChgApprovalStatusByBo(cmBsContractInfoBo);
        return Boolean.TRUE;
    }

    @Override
    public ProcessPersonBo getHTBGSPLCPerson(Long businessId) {
// TODO 按需求返回预设审批人 , 示例全用当前用户作为每个节点的审批人
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setJianshedanwei(getjiansdw());
        return bo;
    }

    /**
     * 获取合同审批流程预设审批人
     */
    @Override
    public ProcessPersonBo getHTSPLCPerson(Long businessId) {
        // TODO 按需求返回预设审批人 , 示例全用当前用户作为每个节点的审批人
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setJianshedanwei(getjiansdw());
        return bo;
    }


    /**
     * 发起合同站点清单审批流程
     */
    @Override
    public Boolean startHTZDQDSPProcess(htzdqdlcBo bo) {
        // TODO 按需求做些业务的校验，如 是否允许发起等
        CmBaContractSheetsBo cmBaContractSheetsBo = new CmBaContractSheetsBo();
        cmBaContractSheetsBo.setBdId(bo.getBdId());
        cmBaContractSheetsBo.setZdId(bo.getZdId());
        cmBaContractSheetsBo.setApprovalStatus("11");
        BaseBsBdVo baseBsBdVo = baseBsBdMapper.selectVoById(bo.getBdId());
        if (ObjectUtils.isNotEmpty(baseBsBdVo)){
            bo.setBdName(baseBsBdVo.getName());
        }
        BaseBsZdVo baseBsZdVo = baseBsZdMapper.selectVoById(bo.getZdId());
        if (ObjectUtils.isNotEmpty(baseBsZdVo)){
            bo.setZdName(baseBsZdVo.getName());
        }
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        String s = wfProcessService.startProcessByDefKey(HTZDQDSPLC_PROCESS_KEY, variables);
        cmBaContractSheetsBo.setProInsId(s);
        iCmBaContractSheetsService.updateApprovalStatusByBo(cmBaContractSheetsBo);
        return Boolean.TRUE;
    }

    /**
     * 获取合同站点清单审批流程预设审批人
     */
    @Override
    public ProcessPersonBo getHTZDQDSPPerson(Long businessId) {
        // TODO 按需求返回预设审批人 , 示例全用当前用户作为每个节点的审批人
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setJianshedanwei(getjiansdw());
        return bo;
    }

    /**
     * 发起开工预付款审批流程
     * @param bo
     * @return
     */
    @Override
    public Boolean startKGYFKProcess(kgyfklcBo bo) {
        // TODO 按需求做些业务的校验，如 是否允许发起等
        CmBsStartAdvanceBo cmBsStartAdvanceBo = new CmBsStartAdvanceBo();
        cmBsStartAdvanceBo.setBdId(bo.getBdId());
        cmBsStartAdvanceBo.setReportFlag("11");
        cmBsStartAdvanceService.updateApprovalStatusByBo(cmBsStartAdvanceBo);
        // 流程表单 variables 会在 监听器中使用
        Map<String, Object> variables = BeanUtil.beanToMap(bo, new HashMap<>(), CopyOptions.create());
        wfProcessService.startProcessByDefKey(KGYFK_PROCESS_KEY, variables);
        return Boolean.TRUE;
    }

    /**
     * 获取开工预付款审批流程预设审批人
     * @param businessId
     * @return
     */
    @Override
    public ProcessPersonBo getKGYFKLCPerson(Long businessId) {
        // TODO 按需求返回预设审批人 , 示例全用当前用户作为每个节点的审批人
        ProcessPersonBo bo = new ProcessPersonBo();
        bo.setXiangmujingli(getUserByPostCode("se"));
        bo.setJiliangyuan(getUserByPostCode("jljly"));
        bo.setZongjian(getUserByPostCode("jldazj"));
        bo.setShenji(getUserByPostCode("sjry"));
        bo.setJianshedanwei(getjiansdw());
        return bo;
    }
}
